1# Mutators Tutorial
2
3<!-- TOC -->
4
5## 3D Space Halving
6Sometimes you want to take a 3D shape like a sphere, and cut it in half.
7The BOSL2 library provides a number of ways to do this:
8
9```openscad-3D
10include <BOSL2/std.scad>
11left_half()
12 sphere(d=100);
13```
14
15```openscad-3D
16include <BOSL2/std.scad>
17right_half()
18 sphere(d=100);
19```
20
21```openscad-3D
22include <BOSL2/std.scad>
23front_half()
24 sphere(d=100);
25```
26
27```openscad-3D
28include <BOSL2/std.scad>
29back_half()
30 sphere(d=100);
31```
32
33```openscad-3D
34include <BOSL2/std.scad>
35bottom_half()
36 sphere(d=100);
37```
38
39```openscad-3D
40include <BOSL2/std.scad>
41top_half()
42 sphere(d=100);
43```
44
45You can use the `half_of()` module if you want to split space in a way not aligned with an axis:
46
47```openscad-3D
48include <BOSL2/std.scad>
49half_of([-1,0,-1])
50 sphere(d=100);
51```
52
53The plane of dissection can be shifted along the axis of any of these operators:
54
55```openscad-3D
56include <BOSL2/std.scad>
57left_half(x=20)
58 sphere(d=100);
59```
60
61```openscad-3D
62include <BOSL2/std.scad>
63back_half(y=-20)
64 sphere(d=100);
65```
66
67```openscad-3D
68include <BOSL2/std.scad>
69bottom_half(z=20)
70 sphere(d=100);
71```
72
73```openscad-3D
74include <BOSL2/std.scad>
75half_of([-1,0,-1], cp=[20,0,20])
76 sphere(d=100);
77```
78
79By default, these operators can be applied to objects that fit in a cube 1000 on a side. If you need
80to apply these halving operators to objects larger than this, you can give the size in the `s=`
81argument:
82
83```openscad-3D
84include <BOSL2/std.scad>
85bottom_half(s=2000)
86 sphere(d=1500);
87```
88
89## 2D Plane Halving
90To cut 2D shapes in half, you will need to add the `planar=true` argument:
91
92```openscad-3D
93include <BOSL2/std.scad>
94left_half(planar=true)
95 circle(d=100);
96```
97
98```openscad-3D
99include <BOSL2/std.scad>
100right_half(planar=true)
101 circle(d=100);
102```
103
104```openscad-3D
105include <BOSL2/std.scad>
106front_half(planar=true)
107 circle(d=100);
108```
109
110```openscad-3D
111include <BOSL2/std.scad>
112back_half(planar=true)
113 circle(d=100);
114```
115
116## Chained Mutators
117If you have a set of shapes that you want to do pair-wise hulling of, you can use `chain_hull()`:
118
119```openscad-3D
120include <BOSL2/std.scad>
121chain_hull() {
122 cube(5, center=true);
123 translate([30, 0, 0]) sphere(d=15);
124 translate([60, 30, 0]) cylinder(d=10, h=20);
125 translate([60, 60, 0]) cube([10,1,20], center=false);
126}
127```
128
129## Extrusion Mutators
130The OpenSCAD `linear_extrude()` module can take a 2D shape and extrude it vertically in a line:
131
132```openscad-3D
133include <BOSL2/std.scad>
134linear_extrude(height=30)
135 zrot(45)
136 square(40,center=true);
137```
138
139The `rotate_extrude()` module can take a 2D shape and rotate it around the Z axis.
140
141```openscad-3D
142include <BOSL2/std.scad>
143rotate_extrude()
144 left(50) zrot(45)
145 square(40,center=true);
146```
147
148In a similar manner, the BOSL2 `cylindrical_extrude()` module can take a 2d shape and extrude it
149out radially from the center of a cylinder:
150
151```openscad-3D
152include <BOSL2/std.scad>
153cylindrical_extrude(or=40, ir=35)
154 text(text="Hello World!", size=10, halign="center", valign="center");
155```
156
157
158## Offset Mutators
159
160### Minkowski Difference
161Openscad provides the `minkowski()` module to trace a shape over the entire surface of another shape:
162
163```openscad-3D
164include <BOSL2/std.scad>
165minkowski() {
166 union() {
167 cube([100,33,33], center=true);
168 cube([33,100,33], center=true);
169 cube([33,33,100], center=true);
170 }
171 sphere(r=8);
172}
173```
174
175However, it doesn't provide the inverse of this operation; to remove a shape from the entire surface
176of another object. For this, the BOSL2 library provides the `minkowski_difference()` module:
177
178```openscad-3D
179include <BOSL2/std.scad>
180minkowski_difference() {
181 union() {
182 cube([100,33,33], center=true);
183 cube([33,100,33], center=true);
184 cube([33,33,100], center=true);
185 }
186 sphere(r=8);
187}
188```
189
190To perform a `minkowski_difference()` on 2D shapes, you need to supply the `planar=true` argument:
191
192```openscad-2D
193include <BOSL2/std.scad>
194minkowski_difference(planar=true) {
195 union() {
196 square([100,33], center=true);
197 square([33,100], center=true);
198 }
199 circle(r=8);
200}
201```
202
203### Round2d
204The `round2d()` module lets you take a 2D shape and round inside and outside corners. The inner concave corners are rounded to the radius `ir=`, while the outer convex corners are rounded to the radius `or=`:
205
206```openscad-2D
207include <BOSL2/std.scad>
208round2d(or=8)
209 star(6, step=2, d=100);
210```
211
212```openscad-2D
213include <BOSL2/std.scad>
214round2d(ir=12)
215 star(6, step=2, d=100);
216```
217
218```openscad-2D
219include <BOSL2/std.scad>
220round2d(or=8,ir=12)
221 star(6, step=2, d=100);
222```
223
224You can use `r=` to effectively set both `ir=` and `or=` to the same value:
225
226```openscad-2D
227include <BOSL2/std.scad>
228round2d(r=8)
229 star(6, step=2, d=100);
230```
231
232### Shell2d
233With the `shell2d()` module, you can take an arbitrary shape, and get the shell outline of it.
234With a positive thickness, the shell is offset outwards from the original shape:
235
236```openscad-2D
237include <BOSL2/std.scad>
238shell2d(thickness=5)
239 star(5,step=2,d=100);
240color("blue")
241 stroke(star(5,step=2,d=100),closed=true);
242```
243
244With a negative thickness, the shell if inset from the original shape:
245
246```openscad-2D
247include <BOSL2/std.scad>
248shell2d(thickness=-5)
249 star(5,step=2,d=100);
250color("blue")
251 stroke(star(5,step=2,d=100),closed=true);
252```
253
254You can give a pair of thickness values if you want it both inset and outset from the original shape:
255
256```openscad-2D
257include <BOSL2/std.scad>
258shell2d(thickness=[-5,5])
259 star(5,step=2,d=100);
260color("blue")
261 stroke(star(5,step=2,d=100),closed=true);
262```
263
264You can add rounding to the outside by passing a radius to the `or=` argument.
265
266```openscad-2D
267include <BOSL2/std.scad>
268shell2d(thickness=-5,or=5)
269 star(5,step=2,d=100);
270```
271
272If you need to pass different radii for the convex and concave corners of the outside, you can pass them as `or=[CONVEX,CONCAVE]`:
273
274```openscad-2D
275include <BOSL2/std.scad>
276shell2d(thickness=-5,or=[5,10])
277 star(5,step=2,d=100);
278```
279
280A radius of 0 can be used to specify no rounding:
281
282```openscad-2D
283include <BOSL2/std.scad>
284shell2d(thickness=-5,or=[5,0])
285 star(5,step=2,d=100);
286```
287
288You can add rounding to the inside by passing a radius to the `ir=` argument.
289
290```openscad-2D
291include <BOSL2/std.scad>
292shell2d(thickness=-5,ir=5)
293 star(5,step=2,d=100);
294```
295
296If you need to pass different radii for the convex and concave corners of the inside, you can pass them as `ir=[CONVEX,CONCAVE]`:
297
298```openscad-2D
299include <BOSL2/std.scad>
300shell2d(thickness=-5,ir=[8,3])
301 star(5,step=2,d=100);
302```
303
304You can use `or=` and `ir=` together to get nice combined rounding effects:
305
306```openscad-2D
307include <BOSL2/std.scad>
308shell2d(thickness=-5,or=[7,2],ir=[7,2])
309 star(5,step=2,d=100);
310```
311
312```openscad-2D
313include <BOSL2/std.scad>
314shell2d(thickness=-5,or=[5,0],ir=[5,0])
315 star(5,step=2,d=100);
316```
317
318
319### Round3d
320### Offset3d
321(To be Written)
322
323
324## Color Manipulators
325The built-in OpenSCAD `color()` module can let you set the RGB color of an object, but it's often
326easier to select colors using other color schemes. You can use the HSL or Hue-Saturation-Lightness
327color scheme with the `hsl()` module:
328
329```openscad-3D
330include <BOSL2/std.scad>
331n = 10; size = 100/n;
332for (a=count(n), b=count(n), c=count(n)) {
333 let( h=360*a/n, s=1-b/(n-1), l=c/(n-1))
334 translate(size*[a,b,c]) {
335 hsl(h,s,l) cube(size);
336 }
337}
338```
339
340You can use the HSV or Hue-Saturation-Value color scheme with the `hsv()` module:
341
342```openscad-3D
343include <BOSL2/std.scad>
344n = 10; size = 100/n;
345for (a=count(n), b=count(n), c=count(n)) {
346 let( h=360*a/n, s=1-b/(n-1), v=c/(n-1))
347 translate(size*[a,b,c]) {
348 hsv(h,s,v) cube(size);
349 }
350}
351```
352
353